package com.mrchi.user.controller;

import com.mrchi.user.VO.ResultVO;
import com.mrchi.user.constant.CookieConstant;
import com.mrchi.user.constant.RedisConstant;
import com.mrchi.user.constant.WxConstants;
import com.mrchi.user.dataobject.UserInfo;
import com.mrchi.user.enums.ResultEnum;
import com.mrchi.user.enums.RoleEnum;
import com.mrchi.user.service.UserService;
import com.mrchi.user.utils.CookieUtil;
import com.mrchi.user.utils.HttpClientUtil;
import com.mrchi.user.utils.ResultVOUtil;
import com.mrchi.user.utils.SignUtil;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/login")
public class LoginController {

	@Autowired
	private UserService userService;

	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	@RequestMapping("/haha")
	public ResultVO haha() {
		return ResultVOUtil.error(88,"打开效果就这样");
	}

		/**
         * 获取微信授权
         * @param request
         * @param response
         * @throws IOException
         */
	@RequestMapping("/wxlogin")
	public void doWxLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String authUrl = WxConstants.AUTH_BASE_URL +
				"appid=" + WxConstants.APPID
				+ "&redirect_uri=" + URLEncoder.encode(WxConstants.REDIRECT_URL)
				+ "&response_type=code"
				+ "&scope=" + WxConstants.SCOPE
				+ "&state=123" +
				"#wechat_redirect";

		// 微信加密签名
		String signature = request.getParameter("signature");
		// 时间戳
		String timestamp = request.getParameter("timestamp");
		// 随机数
		String nonce = request.getParameter("nonce");
		// 随机字符串
		String echostr = request.getParameter("echostr");

		PrintWriter out = response.getWriter();

		if (signature != null && timestamp != null && nonce != null && echostr != null) {
			if (SignUtil.checkSignature(signature, timestamp, nonce)) {
				out.print(echostr);
			}
			out.close();
		} else {
			response.sendRedirect(authUrl);
		}

	}

	/**
	 * 微信登入
	 * @param code
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/doWxCallBack")
	public ResultVO doWxCallBack(String code, HttpServletRequest request, HttpServletResponse response) throws  Exception{
			//通过code换取网页授权access_token
			String access_token_url = WxConstants.ACCESS_TOKEN_BASE_URL
					+ "appid=" + WxConstants.APPID
					+ "&secret=" + WxConstants.APPSECRET
					+ "&code=" + code
					+ "&grant_type=authorization_code";

			//发送请求
			String jsonResult = HttpClientUtil.doGet(access_token_url);
			if (jsonResult == null || "".equals(jsonResult)) {
				System.out.println("认证失败");
				return ResultVOUtil.error(ResultEnum.ROLE_ERROR3);
			}
			JsonObject accessJsonObject = new JsonParser().parse(jsonResult).getAsJsonObject();

			//与开放平台关联要使用unionid
			String openid = accessJsonObject.get("openid").getAsString();
			String access_token = accessJsonObject.get("access_token").getAsString();

			//微信与用户信息的绑定

		ResultVO buyer = buyer(openid, response);
		if (buyer.getCode()!=0){
			if (buyer.getCode()==2){
				return seller(openid,request,response);
			}else {
				// 登录失败, 没有注册,获取用户的微信信息(需scope为 snsapi_userinfo)
				String infoUrl = WxConstants.INFO_BASE_URL
						+ "access_token=" + access_token
						+ "&openid=" + openid
						+ "&lang=zh_CN";
				String userInfoJson = HttpClientUtil.doGet(infoUrl);
				if (userInfoJson == null || "".equals(userInfoJson)) {
					System.out.println("获取用户微信信息失败");
					return ResultVOUtil.error(ResultEnum.ROLE_ERROR2);
				}
				//使用微信的信息
				JsonObject userInfoJsonObject = new JsonParser().parse(userInfoJson).getAsJsonObject();

				System.out.println(userInfoJson);
			}
		}else {
			return buyer;
		}
		return null;
	}
	/**
	 * 买家登录
	 * @param openid 登入id
	 * @param response
	 * @return
	 */
	@GetMapping("/buyer")
	public ResultVO buyer(@RequestParam("openid") String openid,
						  HttpServletResponse response) {
		//1. openid和数据库里的数据是否匹配
		// 从数据库中取出来
		UserInfo userInfo = userService.findByOpenid(openid);
		// 登录失败, 没有注册
		if (userInfo == null) {
			return ResultVOUtil.error(ResultEnum.LOGIN_FAIL);
		}

		//2. 判断角色 , 是不是买家
		if (!RoleEnum.BUYER.getCode().equals(userInfo.getRole())) {
			return ResultVOUtil.error(ResultEnum.ROLE_ERROR);
		}

		//3. cookie里设置openid
		CookieUtil.set(response, CookieConstant.OPENID, openid, CookieConstant.expire);

		return ResultVOUtil.success();
	}

	@GetMapping("/seller")
	public ResultVO seller(@RequestParam("openid") String openid,
						  HttpServletRequest request,
						  HttpServletResponse response) {
		//判断是否已登录, 防止产生多个重复的uuid
		Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
		if (cookie != null &&
				!StringUtils.isEmpty(stringRedisTemplate.opsForValue().get(
						String.format(RedisConstant.TOKEN_TEMPLATE, cookie.getValue())))) {
			return ResultVOUtil.success();
		}

		//1. openid和数据库里的数据是否匹配
		UserInfo userInfo = userService.findByOpenid(openid);
		if (userInfo == null) {
			return ResultVOUtil.error(ResultEnum.LOGIN_FAIL);
		}

		//2. 判断角色, 是不是卖家
		if (!RoleEnum.SELLER.getCode().equals(userInfo.getRole())) {
			return ResultVOUtil.error(ResultEnum.ROLE_ERROR);
		}

		//3. redis设置key=UUID, value=xyz
		String token = UUID.randomUUID().toString();

		stringRedisTemplate.opsForValue().set(
				String.format(RedisConstant.TOKEN_TEMPLATE, token),
				openid,
				CookieConstant.expire,
				TimeUnit.SECONDS);

		//4. cookie里设置token
		CookieUtil.set(response, CookieConstant.TOKEN, token, CookieConstant.expire);

		return ResultVOUtil.success();
	}
/*
	@GetMapping("/wx/wxLogin")
	public void doWxLogin (HttpServletRequest request, HttpServletResponse response) {

		try {
			userService.doWxLogin(request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
 */
}
